package handlers

import (
	"encoding/json"
	"fmt"
	"iot/mqttmodule"
	"iot/sql_models"
	"log"
)

// RegistrationRequestHandler 处理设备注册和绑定的请求
func RegistrationRequestHandler(topic string, payloadData map[string]interface{}) {
	fmt.Printf("注册请求 topic: %s, 数据: %v\n", topic, payloadData)

	client := mqttmodule.GetMQTTClient()
	if client == nil {
		log.Println("MQTT 客户端尚未初始化")
		return
	}

	// 遍历 payloadData，动态识别 tag 值
	for tag, value := range payloadData {
		switch tag {
		case "check-sn":
			handleCheckSN(client, value.(map[string]interface{}))
		case "shop-bind":
			handleShopBind(client, value.(map[string]interface{}))
		case "shop-unbind":
			handleShopUnbind(client, value.(map[string]interface{}))
		case "room-bind":
			handleRoomBind(client, value.(map[string]interface{}))
		case "room-unbind":
			handleRoomUnbind(client, value.(map[string]interface{}))
		case "room-list":
			handleRoomList(client, value.(map[string]interface{}))
		default:
			log.Printf("未知的 tag: %s\n", tag)
		}
	}
}

// // stripResponseWrapper 自动剥离包含 -res 后缀的外层
// func stripResponseWrapper(payloadData map[string]interface{}) map[string]interface{} {
// 	for key, value := range payloadData {
// 		// 如果键名以 "-res" 结尾，且值是一个 map，则剥离这一层
// 		if strings.HasSuffix(key, "-res") {
// 			if innerData, ok := value.(map[string]interface{}); ok {
// 				return innerData
// 			}
// 		}
// 	}
// 	return payloadData
// }

// 1. 处理 check-sn 请求
func handleCheckSN(client *mqttmodule.MQTTClient, payloadData map[string]interface{}) {
	sn, ok := payloadData["sn"].(string)
	if !ok {
		log.Println("sn 字段缺失")
		return
	}

	device, err := sql_models.GetDeviceBySN(sn)
	if err != nil {
		log.Printf("查找设备 %s 失败: %v\n", sn, err)
		client.Publish("general/registration", `{"sn-check-res": {"binded": false}}`, 0, false)
		return
	}

	response := map[string]interface{}{
		"sn-check-res": map[string]interface{}{
			"binded": true,
		},
	}

	if device.ShopID != nil {
		shop, rooms, err := sql_models.GetShopAndRooms(*device.ShopID)
		if err == nil {
			response["sn-check-res"].(map[string]interface{})["shopid"] = shop.ID
			roomList := make([]string, len(rooms))
			for i, room := range rooms {
				roomList[i] = room.RoomID
			}
			response["sn-check-res"].(map[string]interface{})["roomlist"] = roomList
		}
	}

	if device.RoomID != nil {
		response["sn-check-res"].(map[string]interface{})["roomid"] = device.RoomID
	}

	responseJSON, _ := json.Marshal(response)
	client.Publish("general/registration", string(responseJSON), 0, false)
}

// 2. 处理 shop-bind 请求
func handleShopBind(client *mqttmodule.MQTTClient, payloadData map[string]interface{}) {
	sn, ok := payloadData["sn"].(string)
	shopID, shopOk := payloadData["shopid"].(string)
	if !ok || !shopOk {
		log.Println("sn 或 shopid 字段缺失")
		client.Publish("general/registration", `{"shop-bind-res": {"binded": false}}`, 0, false)
		return
	}

	err := sql_models.AssociateDeviceWithShop(sn, shopID)
	if err != nil {
		log.Printf("设备 %s 绑定店铺失败: %v\n", sn, err)
		client.Publish("general/registration", `{"shop-bind-res": {"binded": false}}`, 0, false)
		return
	}

	shop, rooms, err := sql_models.GetShopAndRooms(shopID)
	_ = shop
	if err != nil {
		log.Printf("获取店铺信息失败: %v\n", err)
		client.Publish("general/registration", `{"shop-bind-res": {"binded": false}}`, 0, false)
		return
	}

	roomList := make([]string, len(rooms))
	for i, room := range rooms {
		roomList[i] = room.RoomID
	}

	response := map[string]interface{}{
		"shop-bind-res": map[string]interface{}{
			"binded":   true,
			"roomlist": roomList,
		},
	}

	responseJSON, _ := json.Marshal(response)
	client.Publish("general/registration", string(responseJSON), 0, false)
}

// 3. 处理 shop-unbind 请求
func handleShopUnbind(client *mqttmodule.MQTTClient, payloadData map[string]interface{}) {
	sn, ok := payloadData["sn"].(string)
	if !ok {
		log.Println("sn 字段缺失")
		return
	}

	err := sql_models.UnassociateDeviceWithShop(sn)
	if err != nil {
		log.Printf("设备 %s 解绑店铺失败: %v\n", sn, err)
		client.Publish("general/registration", `{"shop-unbind-res": {"unbinded": false}}`, 0, false)
		return
	}

	client.Publish("general/registration", `{"shop-unbind-res": {"unbinded": true}}`, 0, false)
}

// 4. 处理 room-bind 请求
func handleRoomBind(client *mqttmodule.MQTTClient, payloadData map[string]interface{}) {
	sn, ok := payloadData["sn"].(string)
	roomID, roomOk := payloadData["roomid"].(string)
	if !ok || !roomOk {
		log.Println("sn 或 roomid 字段缺失")
		client.Publish("general/registration", `{"room-bind-res": {"binded": false}}`, 0, false)
		return
	}

	err := sql_models.AssociateDeviceWithRoom(sn, roomID)
	if err != nil {
		log.Printf("设备 %s 绑定房间失败: %v\n", sn, err)
		client.Publish("general/registration", `{"room-bind-res": {"binded": false}}`, 0, false)
		return
	}

	client.Publish("general/registration", `{"room-bind-res": {"binded": true}}`, 0, false)
}

// 5. 处理 room-unbind 请求
func handleRoomUnbind(client *mqttmodule.MQTTClient, payloadData map[string]interface{}) {
	sn, ok := payloadData["sn"].(string)
	if !ok {
		log.Println("sn 字段缺失")
		return
	}

	err := sql_models.UnassociateDeviceWithRoom(sn)
	if err != nil {
		log.Printf("设备 %s 解绑房间失败: %v\n", sn, err)
		client.Publish("general/registration", `{"room-unbind-res": {"unbinded": false}}`, 0, false)
		return
	}

	client.Publish("general/registration", `{"room-unbind-res": {"unbinded": true}}`, 0, false)
}

// 6. 处理 room-list 请求
func handleRoomList(client *mqttmodule.MQTTClient, payloadData map[string]interface{}) {
	shopID, shopOk := payloadData["shopid"].(string)
	if !shopOk {
		log.Println("shopid 字段缺失")
		return
	}

	_, rooms, err := sql_models.GetShopAndRooms(shopID)
	if err != nil {
		log.Printf("获取房间列表失败: %v\n", err)
		client.Publish("general/registration", `{"room-list-res": {"roomlist": []}}`, 0, false)
		return
	}

	roomList := make([]string, len(rooms))
	for i, room := range rooms {
		roomList[i] = room.RoomID
	}

	response := map[string]interface{}{
		"room-list-res": map[string]interface{}{
			"roomlist": roomList,
		},
	}

	responseJSON, _ := json.Marshal(response)
	client.Publish("general/registration", string(responseJSON), 0, false)
}
